package com.badlogic.androidgames.framework.impl;

import java.util.List;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout;

import com.badlogic.androidgames.framework.Audio;
import com.badlogic.androidgames.framework.FileIO;
import com.badlogic.androidgames.framework.Game;
import com.badlogic.androidgames.framework.Graphics;
import com.badlogic.androidgames.framework.Input;
import com.badlogic.androidgames.framework.Input.KeyEvent;
import com.badlogic.androidgames.framework.Screen;
import com.google.ads.Ad;
import com.google.ads.AdListener;
import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;
import com.google.ads.AdRequest.ErrorCode;

public abstract class GLGame extends Activity implements Game, Renderer , AdListener
{
    enum GLGameState {
        Initialized,
        Running,
        Paused,
        Finished,
        Idle
    }
    
    protected AdView adView;
    GLSurfaceView glView;    
    GLGraphics glGraphics;
    Audio audio;
    Input input;
    FileIO fileIO;
    Screen screen;
    GLGameState state = GLGameState.Initialized;
    Object stateChanged = new Object();
    long startTime = System.nanoTime();
    WakeLock wakeLock;
	private RelativeLayout layout;
	private final int SHOW_ADS = 1;
    private final int HIDE_ADS = 0;
    
    public boolean firtTimeAdReceived = false;
    
	 protected Handler handler = new Handler()
	    {
	        @Override
	        public void handleMessage(Message msg) {
	            switch(msg.what) {
	                case SHOW_ADS:
	                {
	                    adView.setVisibility(View.VISIBLE);
	                    break;
	                }
	                case HIDE_ADS:
	                {
	                    adView.setVisibility(View.GONE);
	                    break;
	                }
	            }
	        }
	    };
	
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        layout = new RelativeLayout(this);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                        WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

        glView = new GLSurfaceView(this);
        glView.setRenderer(this);
        layout.addView(glView);
        RelativeLayout.LayoutParams adParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        adParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
        adParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
        adView = new AdView(this, AdSize.BANNER, "a14ee8bd6aca1a3");
       
	    layout.addView(adView, adParams);
	    AdRequest request = new AdRequest();
       //request.setTesting(true);
	    adView.loadAd(request);
	    adView.setAdListener(this);
        setContentView(layout);
        request.setTesting(true);
        glGraphics = new GLGraphics(glView);
        fileIO = new AndroidFileIO(getAssets());
        audio = new AndroidAudio(this);
        input = new AndroidInput(this, glView, 1, 1);
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "GLGame"); 
    }
    
    public void onResume() {
        super.onResume();
        glView.onResume();
        wakeLock.acquire();
    }
    

    @Override
	public Screen getStartScreen()
	{
		// TODO Auto-generated method stub
		return null;
	}

    

	@Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {        
        glGraphics.setGL(gl);
        
        synchronized(stateChanged) {
            if(state == GLGameState.Initialized)
                setScreen(getStartScreen() , true);
            state = GLGameState.Running;
            screen.resume();
            startTime = System.nanoTime();
        }        
    }
    
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {        
    }

    @Override
    public void onDrawFrame(GL10 gl) {                
        GLGameState state = null;
        
        synchronized(stateChanged) {
            state = this.state;
        }
        
        if(state == GLGameState.Running) {
            float deltaTime = (System.nanoTime()-startTime) / 1000000000.0f;
            startTime = System.nanoTime();
            
            screen.update(deltaTime);
            screen.present(deltaTime);
        }
        
        if(state == GLGameState.Paused) {
            screen.pause();            
            synchronized(stateChanged) {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }
        }
        
        if(state == GLGameState.Finished) {
            screen.pause();
            screen.dispose();
            synchronized(stateChanged) {
                this.state = GLGameState.Idle;
                stateChanged.notifyAll();
            }            
        }
        
        List<KeyEvent> keyEvents = input.getKeyEvents();
        for(int i = 0 ; i < keyEvents.size() ; i++)
        {
        	KeyEvent event = keyEvents.get(i); 
        	if(event.keyCode == android.view.KeyEvent.KEYCODE_BACK)
        	{
        		System.out.println("Back pressed");
        	}
        	
        }
    }   
    
    @Override 
    public void onPause() {        
        synchronized(stateChanged) {
            if(isFinishing())            
                state = GLGameState.Finished;
            else
                state = GLGameState.Paused;
            while(true) {
                try {
                    stateChanged.wait();
                    break;
                } catch(InterruptedException e) {         
                }
            }
        }
        wakeLock.release();
        glView.onPause();  
        super.onPause();
    }    
    
    public GLGraphics getGLGraphics() {
        return glGraphics;
    }  
    
    @Override
    public Input getInput() {
        return input;
    }

    @Override
    public FileIO getFileIO() {
        return fileIO;
    }

    @Override
    public Graphics getGraphics() {
        throw new IllegalStateException("We are using OpenGL!");
    }

    @Override
    public Audio getAudio() {
        return audio;
    }

    @Override
    public void setScreen(Screen screen) 
    {
        if (screen == null)
            throw new IllegalArgumentException("Screen must not be null");
        if(this.screen != null)
        {
        	this.screen.pause();
            this.screen.dispose();
        }
        
        screen.resume();
        screen.update(0);
        this.screen = screen;
        
    }
    
    @Override
    public void setScreen(Screen screen , Boolean addAd) {
    	if (screen == null)
    		throw new IllegalArgumentException("Screen must not be null");
    	
    	if(this.screen != null)
        {
        	this.screen.pause();
            this.screen.dispose();
        }
    	screen.resume();
    	screen.update(0);
    	this.screen = screen;
    	
    	  if(addAd)
    	  {
    		  showAds(true);
    	  }
    	  else
    	  {
    		  showAds(false);
    	  }
    
    }
    
    public void showAds(boolean show) {
        handler.sendEmptyMessage(show ? SHOW_ADS : HIDE_ADS);
     }

    @Override
    public Screen getCurrentScreen() {
        return screen;
    }
    
    public void navigateToURL(String url)
    {
    	Intent browse = new Intent( Intent.ACTION_VIEW , Uri.parse(url) );
	    startActivity(browse);
    }
    
    @Override
    public void onDismissScreen(Ad arg0) {
    	System.out.println("onDismissScreen");
    }

    @Override
    public void onLeaveApplication(Ad arg0) {
    	System.out.println("onLeaveApplication");

    }

    @Override
    public void onPresentScreen(Ad arg0) {
    	System.out.println("onPresentScreen");
      
    }

    @Override
    public void onReceiveAd(Ad arg0) 
    {
    	firtTimeAdReceived = true;
    }


	@Override
	public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1)
	{
		firtTimeAdReceived = true;
	}
}
